﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Security.Cryptography;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Net.NetworkInformation;
using NetworkCommsDotNet;
using Microsoft.Phone.Net.NetworkInformation;
using Microsoft.Phone.Info;
using System.Windows;
using System.IO.IsolatedStorage;
using System.Windows.Controls;
using System.Security;
using ImageTools;
using ImageTools.IO.Png;
using Jive.Helpers;
using Jive.Network;
using GalaSoft.MvvmLight.Messaging;
using Jive.Settings;
using JmShared;
using Jive.User;
using System.ComponentModel;

namespace Jive.Helpers
{
    public static class StaticMethods
    {
        private static Dictionary<string, BitmapImage> CustomEmoticonCache = new Dictionary<string, BitmapImage>();
        public static BitmapImage ByteArrayToImage(byte[] array)
        {
            MemoryStream ms = new MemoryStream(array, 0, array.Length);

            // Convert byte[] to Image
            ms.Write(array, 0, array.Length);

            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.SetSource(ms);

            return bitmapImage;
        }

        //public static BitmapSource BitmapFromUri(Uri source)
        //{
        //    var bitmap = new BitmapImage();

        //    try
        //    {
        //        //bitmap.BeginInit();
        //        bitmap.UriSource = source;
        //        //bitmap.CacheOption = BitmapCacheOption.OnLoad;
        //        //bitmap.EndInit();
        //    }
        //    catch (Exception err)
        //    {
        //        bitmap = null;
        //        // NetworkComms.Logger.ErrorException("Error loading image source: " + source.AbsolutePath, err);
        //        Messenger.Default.Send("Error loading image source: " + source.AbsolutePath);
        //    }
        //    return bitmap;
        //}
        /// <summary> 
        /// Save stream to Png.First, determine and delete the file with the same name 
        /// in IsolatedStorage, and then create a new one. 
        /// </summary> 
        /// <param name="stream">The stream of local image or network image</param> 
        public static void SaveToPng(BitmapImage image, string fileName)
        {
            using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (storage.FileExists(fileName))
                {
                    storage.DeleteFile(fileName);
                }

                WriteableBitmap bitmap = new WriteableBitmap(image);
                var img = bitmap.ToImage();
                var encoder = new PngEncoder();
                using (var stream = new IsolatedStorageFileStream(fileName, FileMode.Create, storage))
                {
                    encoder.Encode(img, stream);
                    CustomEmoticonCache[fileName] = image;
                }
            }
        }
        public static void SaveToPng(Image image, string fileName)
        {
            SaveToPng((BitmapImage)image.Source, fileName);
        }
        public static Image LoadImageFromIsolatedStorage(string path)
        {
            try
            {
                Image img = new Image();

                img.Source = LoadBitmapImageFromIsolatedStorage(path);//CustomEmoticonCache[path];
                //BitmapImage bi = new BitmapImage();

                //using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                //{
                //    using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(path, FileMode.Open, FileAccess.Read))
                //    {
                //        bi.SetSource(fileStream);
                //        img.Height = bi.PixelHeight;
                //        img.Width = bi.PixelWidth;

                //    }
                //}

                return img;
            }
            catch (Exception err)
            {
                Debug.WriteLine(err);
                return null;
            }

        }
        public static BitmapImage LoadBitmapImageFromIsolatedStorage(string path)
        {
            if (String.IsNullOrEmpty(path))
                return null;
            try
            {
                BitmapImage bi = new BitmapImage();
                if (!CustomEmoticonCache.ContainsKey(path))
                {


                    using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(path, FileMode.Open, FileAccess.Read))
                        {
                            bi.SetSource(fileStream);
                            //img.Height = bi.PixelHeight;
                            //img.Width = bi.PixelWidth;

                        }
                    }
                    CustomEmoticonCache[path] = bi;
                }
                else
                    bi = CustomEmoticonCache[path];

                return bi;
            }
            catch (Exception err)
            {
                Debug.WriteLine(err);
                return null;
            }

        }
        public static Byte[] LoadImageAsByteArray(string path)
        {
            try
            {
                using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(path, FileMode.Open, FileAccess.Read))
                    {
                        byte[] bytes = new byte[fileStream.Length];
                        fileStream.Read(bytes, 0, (int)fileStream.Length);
                        return bytes;
                    }
                }
            }
            catch (Exception err)
            {
                Debug.WriteLine(err);
                return null;
            }
        }
        public static string FileNameFriendly(string n)
        {
            n = n.Replace("*", "~");
            n = n.Replace("|", "-");
            n = n.Replace(@"\", "'");
            n = n.Replace("/", "_");
            n = n.Replace(":", ".");
            n = n.Replace("<", "(");
            n = n.Replace(">", ")");
            n = n.Replace("?", "^");
            n = n.Replace('"'.ToString(CultureInfo.InvariantCulture), "");
            n = n.Trim();
            return n;
        }

        public static byte[] ImageToByteArray(string filePath)
        {

            FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            
                using (BinaryReader br = new BinaryReader(fs))
                {

                    byte[] imageBytes = br.ReadBytes((int)fs.Length);
                    return imageBytes;
                    //br.Close();

                    //fs.Close();
                }
            
            // return imageBytes;
        }

        public static List<string> SplitLongMessage(string str, int chunkSize)
        {
            if (str.Length < chunkSize)
                return null;
            int totalLength = str.Length;
            List<string> strList = new List<string>();
            int i = 0;
            while (true)
            {
                if ((totalLength - i) < chunkSize)
                {
                    strList.Add(str.Substring(i, totalLength - i));
                    break;
                }
                string sub = str.Substring(i, chunkSize);
                int lastSpaceIndex = sub.LastIndexOf(' ');
                if (lastSpaceIndex == -1)
                    lastSpaceIndex = 400;

                strList.Add(str.Substring(i, lastSpaceIndex));
                i += lastSpaceIndex;


            }
            return strList;
        }

        public static int RandomNumber(int from, int to)
        {
            Random r = new Random(DateTime.Now.Millisecond);
            return r.Next(from, to);

        }
        public static string CombinePath(params object[] values)
        {
            string path = "";
            foreach (var str in values)
            {
                path += str.ToString().TrimStart(Path.DirectorySeparatorChar).EndsWith(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture)) ? str : str.ToString() + Path.DirectorySeparatorChar;
            }

            return path.TrimEnd(Path.DirectorySeparatorChar);
        }

        public static string ObjectToString<T>(object input)
        {
            MemoryStream stream = new MemoryStream();
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            ser.WriteObject(stream, input);
            byte[] bytes = stream.ToArray();
            return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
        }
        public static string ContactEmoticonToString(ContactEmoticon input)
        {
            MemoryStream stream = new MemoryStream();
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ContactEmoticon));
            ser.WriteObject(stream, input);
            byte[] b = stream.ToArray();
            return Encoding.UTF8.GetString(b, 0, b.Length);
        }

        public static T StringToObject<T>(string input)
        {
            if (String.IsNullOrEmpty(input))
                return default(T);
            MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(input));
            DataContractJsonSerializer ser = null;
            try
            {
                ser = new DataContractJsonSerializer(typeof(T));
            }
            catch (Exception e)
            {
                Messenger.Default.Send(e.ToString());
                Debug.WriteLine(e.ToString());
            }
            return (T)ser.ReadObject(stream);
        }
        public static string DictionaryToString<TK, TV>(Dictionary<TK, TV> input)
        {
            MemoryStream stream = new MemoryStream();
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Dictionary<TK, TV>));

            ser.WriteObject(stream, input);
            byte[] bytes = stream.ToArray();
            string str = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
            stream.Dispose();
            return str;
        }
        public static string ListToString<T>(List<T> input)
        {
            MemoryStream stream = new MemoryStream();
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<T>));
            ser.WriteObject(stream, input);
            byte[] bytes = stream.ToArray();
            string str = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
            stream.Dispose();
            return str;
        }
        public static Dictionary<TK, TV> StringToDictionary<TK, TV>(string input)
        {
            if (String.IsNullOrEmpty(input))
                return new Dictionary<TK, TV>();
            MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(input));

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Dictionary<TK, TV>));
            Dictionary<TK, TV> dic = (Dictionary<TK, TV>)ser.ReadObject(stream);
            stream.Dispose();
            return dic;
        }
        public static List<T> StringToList<T>(string input)
        {
            if (String.IsNullOrEmpty(input))
                return new List<T>();
            MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(input));
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<T>));
            List<T> lst = (List<T>)ser.ReadObject(stream);
            stream.Dispose();
            return lst;
        }

        public static bool ValidateEmoticonShortcut(string str, out string error)
        {

            return ValidateEmoticonShortcut(str, "", out error);
        }
        public static bool ValidateEmoticonShortcut(string str, string exludeShortcut, out string error)
        {
            error = "";
            if (DesignerProperties.IsInDesignTool)
                return true;
            List<string> keys = StaticSettings.GetEmoticons(Client.ClientInstance.CurrentUserInfo.UserID, true, true).Keys.ToList();
            if (!String.IsNullOrEmpty(exludeShortcut))
            {
                if (keys.Contains(exludeShortcut))
                    keys.Remove(exludeShortcut);
            }
            if (str.Length == 1)
            {
                error = "Minimum 2 characters";
                return false;
            }
            if (str.Length > 10)
            {
                error = "Max 10 characters";
                return false;
            }

            if (keys.FindAll(x => x.Contains(str)).Count > 0)
            {
                error = "Shortcut already in use or conflicted";
                return false;
            }
            return true;
        }
        public static string ColorToHexString(Color color)
        {
            byte[] bytes = new byte[3];
            bytes[0] = color.R;
            bytes[1] = color.G;
            bytes[2] = color.B;
            char[] chars = new char[bytes.Length * 2];
            for (int i = 0; i < bytes.Length; i++)
            {
                int b = bytes[i];
                chars[i * 2] = HexDigits[b >> 4];
                chars[i * 2 + 1] = HexDigits[b & 0xF];
            }
            string str = "#FF" + new string(chars);
            return str;
        }

        private static readonly char[] HexDigits = {
         '0', '1', '2', '3', '4', '5', '6', '7',
         '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

        public static bool ParseFontStyle(string fontStyle, out FontStyle fStyle, out FontWeight fWeight)
        {
            try
            {
                fStyle = FontStyles.Normal;
                fWeight = FontWeights.Normal;
                switch (fontStyle)
                {
                    case "Light":
                        fWeight = FontWeights.Light;
                        fStyle = FontStyles.Normal;
                        break;
                    case "Regular":
                        fWeight = FontWeights.Normal;
                        fStyle = FontStyles.Normal;
                        break;
                    case "Italic":
                        fStyle = FontStyles.Italic;
                        fWeight = FontWeights.Normal;
                        break;
                    case "Semibold":
                        fWeight = FontWeights.SemiBold;
                        fStyle = FontStyles.Normal;
                        break;
                    case "Bold":
                        fWeight = FontWeights.Bold;
                        fStyle = FontStyles.Normal;
                        break;
                    case "Bold Italic":
                        fWeight = FontWeights.Bold;
                        fStyle = FontStyles.Italic;
                        break;
                    case "Light Oblique":
                        fWeight = FontWeights.Light;
                        fStyle = FontStyles.Normal;
                        break;
                    case "Semibold Oblique":
                        fWeight = FontWeights.SemiBold;
                        fStyle = FontStyles.Normal;
                        break;

                }
            }
            catch (Exception err)
            {
                Debug.WriteLine("Exception parsing  font style: {0}", err);
                fStyle = FontStyles.Normal; ;
                fWeight = FontWeights.Normal;
                return false;
            }
            return true;
        }
        public static Color ConvertColor(Color c)
        {
            //SolidColorBrush temp = new SolidColorBrush(c);
            if (c == Colors.Red)
                return PhoneThemeColors.Red;
            else if (c == Colors.Blue)
                return PhoneThemeColors.Cobalt;
            else if (c == Colors.Green)
                return PhoneThemeColors.Emerald;
            else if (ColorToHexString(c) == "#FF800000")
                return PhoneThemeColors.Crimson;
            else if (c == Colors.Magenta)
                return PhoneThemeColors.Magenta;
            else if (ColorToHexString(c) == "#FF808000")
                return PhoneThemeColors.Olive;
            else if (ColorToHexString(c) == "#FF000080")
                return PhoneThemeColors.Cobalt;
            else if (c == Colors.Purple)
                return PhoneThemeColors.Violet;
            else if (ColorToHexString(c) == "#FF008080")
                return PhoneThemeColors.Teal;
            else if (c == Colors.Gray)
                return PhoneThemeColors.Steel;
            else if (ColorToHexString(c) == "#FF00FF00")
                return PhoneThemeColors.Lime;
            else if (c == Colors.Yellow)
                return PhoneThemeColors.Yellow;
            else if (ColorToHexString(c) == "#FFFF00FF")
                return PhoneThemeColors.Pink;
            else if (ColorToHexString(c) == "FF00FFFF")
                return PhoneThemeColors.Cyan;

            else return c;
        }
        public static Color ColorFromHex(String hex)
        {
            if (String.IsNullOrEmpty(hex))
                return Colors.White;
            //remove the # at the front
            hex = hex.Replace("#", "");

            byte a = 255;
            byte r = 255;
            byte g = 255;
            byte b = 255;

            int start = 0;

            //handle ARGB strings (8 characters long)
            if (hex.Length == 8)
            {
                a = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
                start = 2;
            }

            //convert RGB characters to bytes
            r = byte.Parse(hex.Substring(start, 2), System.Globalization.NumberStyles.HexNumber);
            g = byte.Parse(hex.Substring(start + 2, 2), System.Globalization.NumberStyles.HexNumber);
            b = byte.Parse(hex.Substring(start + 4, 2), System.Globalization.NumberStyles.HexNumber);

            return Color.FromArgb(a, r, g, b);
        }
        public static string EncodePassword(string password)
        {
            var sha1 = new System.Security.Cryptography.SHA1Managed();
            return string.Join("", sha1.ComputeHash(Encoding.UTF8.GetBytes(password)).Select(x => x.ToString("X2"))).ToLower();
        }
    }
}
